package com.meizi.codegenerate.generate.server.domain.repository.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.github.javaparser.StaticJavaParser;
import com.github.javaparser.ast.CompilationUnit;
import com.github.javaparser.ast.Modifier;
import com.github.javaparser.ast.NodeList;
import com.github.javaparser.ast.body.*;
import com.github.javaparser.ast.expr.*;
import com.github.javaparser.ast.stmt.*;
import com.github.javaparser.ast.type.ClassOrInterfaceType;
import com.github.javaparser.ast.type.Type;
import com.meizi.codegenerate.constant.AnnotationSettingValueConstant;
import com.meizi.codegenerate.constant.JavaClassNameConstant;
import com.meizi.codegenerate.constant.MethodNameConstant;
import com.meizi.codegenerate.constant.TableNameConstant;
import com.meizi.codegenerate.entity.ProjectPositionEntity;
import com.meizi.codegenerate.entity.TablesEntity;
import com.meizi.codegenerate.generate.server.domain.repository.dao.DaoGenerate;
import com.meizi.codegenerate.packagegenerate.PackageGenerate;
import com.meizi.codegenerate.tool.page.PageData;
import com.meizi.codegenerate.tool.service.impl.CrudServiceImpl;
import com.meizi.codegenerate.utils.AnnotationUtils;
import com.meizi.codegenerate.utils.AttributeConvertUtils;
import com.meizi.utils.BeanConvertUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.FileUtils;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.io.File;
import java.io.IOException;
import java.math.BigDecimal;
import java.util.*;

/**
 * @author pc
 * @date 2024/2/6 - 14:42 - 星期二
 * @project lambda
 * @package com.meizi.codegenerate.generate.server.domain.repository.impl
 * @by GG Bomd 猪猪侠
 * 生成 仓储曾实现
 */
@Slf4j
public class RepositoryGenerate {

    /**
     * 生成仓储层实现类
     * @param tableName
     * @param tablesComment
     * @param projectPosition
     * @param paramQueryBody
     * @param className
     */
    public static void createRepositoryGenerate(String tableName, TablesEntity tablesComment,
                                                ProjectPositionEntity projectPosition, String paramQueryBody,
                                                String className) throws IOException {
        // 在相应的路径下创建对应的文件
        String serviceUrl = PackageGenerate.obtainDomainRepositoryImplUrl(projectPosition);

        //获取service java类名
        String repositoryName = AttributeConvertUtils.tableNameToJava
                (tableName, TableNameConstant.TABLE_PREFIX, true)
                + JavaClassNameConstant.REPOSITORY;

        String valueName = AttributeConvertUtils.tableNameToJava
                (tableName, TableNameConstant.TABLE_PREFIX, false)
                + JavaClassNameConstant.REPOSITORY;
        // 获取完成的文件路径创建文件
        String fullPath = serviceUrl + repositoryName + TableNameConstant.JAVA;
        log.info("创建 domain 下Repository路径 fullPath = {}", fullPath);

        CompilationUnit compilationUnit = new CompilationUnit();

        // 添加package
        compilationUnit.setPackageDeclaration(PackageGenerate.domainRepositoryImplPackage(projectPosition));
        compilationUnit.addImport("org.springframework.context.annotation.Primary");
        compilationUnit.addImport("org.springframework.stereotype.Service");
        compilationUnit.addImport("javax.annotation.Resource");

        // 添加接口文件
        ClassOrInterfaceDeclaration declaration = compilationUnit.addClass(repositoryName).setPublic(true);

        // 获取mapper
        String mapperName = AttributeConvertUtils.tableNameToJava
                (tableName, TableNameConstant.TABLE_PREFIX, true)
                + JavaClassNameConstant.MAPPER;

        // 获取entity
        String entityTableName = AttributeConvertUtils.tableNameToJava
                (tableName, TableNameConstant.TABLE_PREFIX, true)
                + JavaClassNameConstant.ENTITY;

        // modelName
        String modelName = AttributeConvertUtils.tableNameToJava
                (tableName, TableNameConstant.TABLE_PREFIX, true);

        // 继承CrudServiceImpl接口
        Type type1 = new ClassOrInterfaceType(null, mapperName);
        Type type2 = new ClassOrInterfaceType(null, entityTableName);
        Type type3 = new ClassOrInterfaceType(null, modelName);
        ClassOrInterfaceType crud = new ClassOrInterfaceType(null, CrudServiceImpl.class.getSimpleName());
        crud.setTypeArguments(type1, type2, type3);
        declaration.addExtendedType(crud);

        // 实现IRepository 接口
        declaration.addImplementedType(className);
        //添加类级别注释
        declaration.setJavadocComment(tablesComment.getTableComment() + " 仓储层接口实现");
        LinkedHashMap<String, Object> map = new LinkedHashMap<>();
        // 添加类级别注解
        declaration.addAnnotation(Primary.class);
        map.put(AnnotationSettingValueConstant.SERVICE_VALUE, valueName);
        declaration.addAnnotation(AnnotationUtils.setAnnotation(Service.class, new NodeList<>(),
                map));
        map.clear();

        // 注入相关的类
        // translatorName
        String translatorName = AttributeConvertUtils.tableNameToJava
                (tableName, TableNameConstant.TABLE_PREFIX, true)
                + JavaClassNameConstant.TRANSLATOR;
        String translatorValue = AttributeConvertUtils.tableNameToJava
                (tableName, TableNameConstant.TABLE_PREFIX, false)
                + JavaClassNameConstant.TRANSLATOR;
        map.put(AnnotationSettingValueConstant.RESOURCE_NAME, translatorValue);
        map.put(AnnotationSettingValueConstant.SERVICE_TYPE, translatorName.getBytes());
        declaration.addField(translatorName, translatorValue, Modifier.Keyword.PRIVATE)
                .addAnnotation(AnnotationUtils.setAnnotation(Resource.class, new NodeList<>(), map));
        map.clear();

        //实现方法 getWrapper
        MethodDeclaration getWrapperImpl = getWrapperImpl(MethodNameConstant.REPOSITORY_GET_WRAPPER, paramQueryBody, entityTableName);
        declaration.addMember(getWrapperImpl);


        // 获取到 ？？paramQueryBody 类拿到里面属性
        Map<String, Object> paramsAttribute = new LinkedHashMap<>();
        String queryPath = PackageGenerate.obtainQueryUrl(projectPosition);
        String queryFilePath = queryPath + paramQueryBody + ".java";
        CompilationUnit queryCu = StaticJavaParser.parse(new File(queryFilePath));
        queryCu.findAll(FieldDeclaration.class).forEach(field -> {
            String fieldType = field.getElementType().asString();
            field.getVariables().forEach(variable -> {
                String fieldName = variable.getName().asString();
                //System.out.println("Field Type: " + fieldType + ", Field Name: " + fieldName);
                log.info("PageParamQueryBodyAttribute Field Type: {}, Field Name: {}", fieldType, fieldName);
                // 将变量名作为key 类型作为value值
                paramsAttribute.put(fieldName, fieldType);
            });
        });

        // 获取到 ？？entity 类拿到里面属性
        Map<String, List<String>> entityAttribute = new LinkedHashMap<>();
        String entityPath = PackageGenerate.obtainEntityUrl(projectPosition);
        String entityFilePath = entityPath + entityTableName + ".java";
        CompilationUnit entityCu = StaticJavaParser.parse(new File(entityFilePath));
        entityCu.findAll(FieldDeclaration.class).forEach(field -> {
            String fieldType = field.getElementType().asString();
            field.getVariables().forEach(variable -> {
                String fieldName = variable.getName().asString();
                //System.out.println("Field Type: " + fieldType + ", Field Name: " + fieldName);
                log.info("entityAttribute Field Type: {}, Field Name: {}", fieldType, fieldName);
                // 检查属性类型在Map中是否存在，若存在则取出相应列表，若不存在则创建新列表
                // 将类型作为key 变量作为value
                List<String> fieldNames = entityAttribute.getOrDefault(fieldType, new ArrayList<>());
                fieldNames.add(fieldName);
                entityAttribute.put(fieldType, fieldNames);
            });
        });

        //自定义方法 getWrapper
        MethodDeclaration getWrapperMethod = getWrapper(MethodNameConstant.REPOSITORY_GET_WRAPPER, paramQueryBody, entityTableName, paramsAttribute, entityAttribute);
        declaration.addMember(getWrapperMethod);

        //实现方法 expandWrapper
        MethodDeclaration expandWrapperMethod = expandWrapper(MethodNameConstant.REPOSITORY_EXPAND_WRAPPER, paramQueryBody, entityTableName);
        declaration.addMember(expandWrapperMethod);

        //实现方法 getList
        MethodDeclaration getListMethod = getList(MethodNameConstant.SERVICE_GET_LIST, paramQueryBody, modelName, translatorValue, entityTableName);
        declaration.addMember(getListMethod);

        //实现方法 getPageList
        MethodDeclaration getPageListMethod = getPageList(MethodNameConstant.SERVICE_GET_PAGE_LIST, paramQueryBody, modelName, translatorValue, entityTableName);
        declaration.addMember(getPageListMethod);

        //实现方法 getCount
        MethodDeclaration getCountMethod = getCount(MethodNameConstant.SERVICE_GET_COUNT, paramQueryBody);
        declaration.addMember(getCountMethod);

        //实现方法 exists
        MethodDeclaration existsMethod = exists(MethodNameConstant.SERVICE_EXISTS, paramQueryBody);
        declaration.addMember(existsMethod);

        //实现方法 DetailById
        MethodDeclaration getDetailByIdMethod = getDetailById(MethodNameConstant.SERVICE_GET_DETAIL_BYID,modelName, translatorValue, entityTableName);
        declaration.addMember(getDetailByIdMethod);

        //实现方法 create
        MethodDeclaration createMethod = create(MethodNameConstant.SERVICE_CREATE, modelName, entityTableName);
        declaration.addMember(createMethod);

        //实现方法 createBathSize
        MethodDeclaration createBatchSizeMethod = createBathSize(MethodNameConstant.SERVICE_CREATE_BATH, modelName, entityTableName);
        declaration.addMember(createBatchSizeMethod);

        //实现方法 createBath
        MethodDeclaration createBatchMethod = createBath(MethodNameConstant.SERVICE_CREATE_BATH, modelName, entityTableName);
        declaration.addMember(createBatchMethod);

        //实现方法 updateModel
        MethodDeclaration updateModelMethod = updateModel(MethodNameConstant.SERVICE_UPDATE_MODEL, modelName, entityTableName);
        declaration.addMember(updateModelMethod);

        //实现方法 updateModelBath
        MethodDeclaration updateModelBathMethod = updateModelBath(MethodNameConstant.SERVICE_UPDATE_MODEL_BATH, modelName, entityTableName, paramQueryBody);
        declaration.addMember(updateModelBathMethod);

        //实现方法 saveModel
        MethodDeclaration saveModelMethod = saveModel(MethodNameConstant.SERVICE_SAVE_MODEL, modelName, entityTableName);
        declaration.addMember(saveModelMethod);

        //实现方法 delete
        MethodDeclaration deleteMethod = delete(MethodNameConstant.SERVICE_DELETE, paramQueryBody);
        declaration.addMember(deleteMethod);

        //实现方法 deleteById
        MethodDeclaration deleteByIdMethod = deleteById(MethodNameConstant.SERVICE_DELETE_BYID, entityTableName);
        declaration.addMember(deleteByIdMethod);

        log.info("生成Repository接口 compilationUnit = {}", compilationUnit);

        /**
         * 把字符串写入文件
         * 参数1：需要写入的文件，如果文件不存在，将自动创建。  参数2：需要写入的内容
         * 参数3：编码格式     参数4：是否为追加模式（ ture: 追加模式，把字符串追加到原内容后面）
         */
        FileUtils.writeStringToFile(new File(fullPath), compilationUnit.toString(), "UTF-8", false);

        // 生成dao
        DaoGenerate.createDaoGenerate(tableName, tablesComment, projectPosition,entityTableName);
    }

    /**
     * 生成 deleteById 方法
     * @param serviceDeleteByid
     * @return
     */
    private static MethodDeclaration deleteById(String serviceDeleteByid, String entityTableName) {

        String id = "id";
        String count = "count";
        String wrapper = "wrapper";
        String lambda = "lambda";
        String lambdaWrapper = "lambdaWrapper";
        String getId = "getId";

        // 添加返回值类型
        ClassOrInterfaceType type = new ClassOrInterfaceType(null, Integer.class.getSimpleName());

        // 生成方法 updateModel
        MethodDeclaration methodDeclaration = new MethodDeclaration();
        methodDeclaration.setModifiers(Modifier.Keyword.PUBLIC);
        methodDeclaration.setType(type);
        methodDeclaration.setName(serviceDeleteByid);
        methodDeclaration.addAnnotation(Override.class);
        methodDeclaration.addParameter(new Parameter(new ClassOrInterfaceType(null, Long.class.getSimpleName()), id));

        BlockStmt blockStmt = new BlockStmt();

        // 生成 if(id == null){ return 0; }
        BinaryExpr isEmptyCall = new BinaryExpr(
                new NameExpr(id),
                new NullLiteralExpr(null),
                BinaryExpr.Operator.EQUALS
        );
        IfStmt ifIsEmpty = new IfStmt(
                isEmptyCall,
                new ReturnStmt(new IntegerLiteralExpr("0")),
                null
        );
        blockStmt.addStatement(ifIsEmpty);

        // 生成 QueryWrapper<T> wrapper = new QueryWrapper<>();
        ClassOrInterfaceType queryWrapperType = new ClassOrInterfaceType(null, QueryWrapper.class.getSimpleName());
        ClassOrInterfaceType name = new ClassOrInterfaceType(null, entityTableName);
        queryWrapperType.setTypeArguments(name);
        ObjectCreationExpr initializationExpr = new ObjectCreationExpr(
                null, queryWrapperType, NodeList.nodeList());
        VariableDeclarator variableDeclarator = new VariableDeclarator(queryWrapperType,
                wrapper, initializationExpr);
        VariableDeclarationExpr variableDeclarationExpr = new VariableDeclarationExpr(variableDeclarator);
        blockStmt.addStatement(variableDeclarationExpr);

        // LambdaQueryWrapper<> lambdaWrapper = wrapper.lambda();
        ClassOrInterfaceType LambdaQueryWrapper = new ClassOrInterfaceType(null, LambdaQueryWrapper.class.getSimpleName());

        LambdaQueryWrapper.setTypeArguments(name);
        MethodCallExpr methodCall = new MethodCallExpr(
                new NameExpr(wrapper),
                lambda
        );
        VariableDeclarationExpr lambdaWrapperVar = new VariableDeclarationExpr(
                new VariableDeclarator(
                        LambdaQueryWrapper,
                        lambdaWrapper,
                        methodCall
                )
        );
        blockStmt.addStatement(lambdaWrapperVar);

        String eq =  lambdaWrapper + ".eq(%s, %s);";
        blockStmt.addStatement(String.format(eq, entityTableName + "::" + getId, "id"));

        // 生成 Integer count = baseDao.delete(wrapper);
        MethodCallExpr methodCallExpr = new MethodCallExpr(
                new NameExpr("baseDao"),
                MethodNameConstant.SERVICE_DELETE
        );
        methodCallExpr.addArgument(wrapper);
        VariableDeclarationExpr resultValuesVar = new VariableDeclarationExpr(
                new VariableDeclarator(
                        type,
                        count,
                        methodCallExpr
                )
        );
        blockStmt.addStatement(resultValuesVar);

        blockStmt.addStatement(new ReturnStmt(new NameExpr(count)));
        methodDeclaration.setBody(blockStmt);
        return methodDeclaration;
    }

    /**
     * 生成 delete 方法
     * @param serviceDelete
     * @param paramQueryBody
     * @return
     */
    private static MethodDeclaration delete(String serviceDelete, String paramQueryBody) {

        String condition = "condition";
        String result = "result";
        String baseDao = "baseDao";

        // 添加返回值类型
        ClassOrInterfaceType type = new ClassOrInterfaceType(null, Integer.class.getSimpleName());

        // 生成方法 updateModel
        MethodDeclaration methodDeclaration = new MethodDeclaration();
        methodDeclaration.setModifiers(Modifier.Keyword.PUBLIC);
        methodDeclaration.setType(type);
        methodDeclaration.setName(serviceDelete);
        methodDeclaration.addAnnotation(Override.class);
        methodDeclaration.addParameter(new Parameter(new ClassOrInterfaceType(null, paramQueryBody), condition));

        BlockStmt body = new BlockStmt();
        // 生成 if(model == null){ return 0; }
        BinaryExpr isEmptyCall = new BinaryExpr(
                new NameExpr(condition),
                new NullLiteralExpr(null),
                BinaryExpr.Operator.EQUALS
        );
        IfStmt ifIsEmpty = new IfStmt(
                isEmptyCall,
                new ReturnStmt(new IntegerLiteralExpr("0")),
                null
        );
        body.addStatement(ifIsEmpty);

        // Integer count = baseDao.delete(getWrapper(condition));
        MethodCallExpr delete = new MethodCallExpr(
                new NameExpr(baseDao),
                MethodNameConstant.SERVICE_DELETE,
                NodeList.nodeList(
                        new MethodCallExpr(
                                new NameExpr("this"), // getWrapper 方法调用
                                MethodNameConstant.REPOSITORY_GET_WRAPPER,
                                NodeList.nodeList(new NameExpr(condition)) // 参数：condition
                        )
                )
        );
        VariableDeclarationExpr resultSelectCount = new VariableDeclarationExpr(
                new VariableDeclarator(
                        type,
                        result,
                        delete
                )
        );
        body.addStatement(resultSelectCount);

        // 生成返回语句: return result;
        body.addStatement(new ReturnStmt(new NameExpr(result)));

        methodDeclaration.setBody(body);
        return methodDeclaration;
    }

    /**
     * \生成 saveModel 方法
     * @param serviceSaveModel
     * @param modelName
     * @param entityTableName
     * @return
     */
    private static MethodDeclaration saveModel(String serviceSaveModel, String modelName, String entityTableName) {

        String model = "model";
        String getId = "getId";
        String count = "count";

        // 添加返回值类型
        ClassOrInterfaceType type = new ClassOrInterfaceType(null, Integer.class.getSimpleName());

        // 生成方法 updateModel
        MethodDeclaration methodDeclaration = new MethodDeclaration();
        methodDeclaration.setModifiers(Modifier.Keyword.PUBLIC);
        methodDeclaration.setType(type);
        methodDeclaration.setName(serviceSaveModel);
        methodDeclaration.addAnnotation(Override.class);
        methodDeclaration.addParameter(new Parameter(new ClassOrInterfaceType(null, modelName), model));

        BlockStmt body = new BlockStmt();

        // if(model == null){ return 0; }
        BinaryExpr isEmptyModelCall = new BinaryExpr(
                new NameExpr(model),
                new NullLiteralExpr(null),
                BinaryExpr.Operator.EQUALS
        );
        IfStmt ifIsEmpty = new IfStmt(
                isEmptyModelCall,
                new ReturnStmt(new IntegerLiteralExpr("0")),
                null
        );
        body.addStatement(ifIsEmpty);

        // Integer count = 0;
        VariableDeclarationExpr resultDeclaration = new VariableDeclarationExpr(
                new VariableDeclarator(
                        new ClassOrInterfaceType().setName(Integer.class.getSimpleName()),
                        count,
                        new IntegerLiteralExpr("0")
                )
        );
        body.addStatement(resultDeclaration);

        /**
         * if(model.getId() == null){
         * 			count = this.create(model);
         * 		        } else {
         * 			count = this.updateModel(model);
         *        }
         */
        // 创建 if 部分语句
        MethodCallExpr getIdMethodCall  = new MethodCallExpr(new NameExpr(model), getId);
        BinaryExpr conditionExpr = new BinaryExpr(getIdMethodCall, new NullLiteralExpr(), BinaryExpr.Operator.EQUALS);

        // 创建 if 语句的分支
        MethodCallExpr createMethodCall   = new MethodCallExpr(new ThisExpr(), MethodNameConstant.SERVICE_CREATE, NodeList.nodeList(new NameExpr(model)));
        AssignExpr createAssignExpr = new AssignExpr(new NameExpr(count), createMethodCall, AssignExpr.Operator.ASSIGN);
        ExpressionStmt createStmt = new ExpressionStmt(createAssignExpr);

        // 创建 if 语句的 else 分支
        MethodCallExpr updateModelMethodCall = new MethodCallExpr(new ThisExpr(), MethodNameConstant.SERVICE_UPDATE_MODEL, NodeList.nodeList(new NameExpr(model)));
        AssignExpr updateModelAssignExpr = new AssignExpr(new NameExpr(count), updateModelMethodCall, AssignExpr.Operator.ASSIGN);
        ExpressionStmt updateModelStmt = new ExpressionStmt(updateModelAssignExpr);

        // 创建 if-else 语句
        IfStmt ifStmt = new IfStmt(conditionExpr, createStmt, new BlockStmt(NodeList.nodeList(updateModelStmt)));
        body.addStatement(ifStmt);

        // 生成 return count
        body.addStatement(new ReturnStmt(new NameExpr(count)));
        methodDeclaration.setBody(body);
        return methodDeclaration;
    }

    /**
     * 生成 updateModelBath 方法
     * @param serviceUpdateModelBath
     * @param modelName
     * @param entityTableName
     * @return
     */
    private static MethodDeclaration updateModelBath(String serviceUpdateModelBath, String modelName, String entityTableName, String paramQueryBody) {

        String model = "model";
        String result = "result";
        String entity = "entity";
        String baseDao = "baseDao";
        String condition = "condition";

        // 添加返回值类型
        ClassOrInterfaceType type = new ClassOrInterfaceType(null, Integer.class.getSimpleName());

        // 生成方法 updateModel
        MethodDeclaration methodDeclaration = new MethodDeclaration();
        methodDeclaration.setModifiers(Modifier.Keyword.PUBLIC);
        methodDeclaration.setType(type);
        methodDeclaration.setName(serviceUpdateModelBath);
        methodDeclaration.addAnnotation(Override.class);
        methodDeclaration.addParameter(new Parameter(new ClassOrInterfaceType(null, modelName), model));
        methodDeclaration.addParameter(new Parameter(new ClassOrInterfaceType(null, paramQueryBody), condition));

        BlockStmt body = new BlockStmt();
        // 生成 if(model == null || condition == null){ return 0; }
        BinaryExpr isEmptyModelCall = new BinaryExpr(
                new NameExpr(model),
                new NullLiteralExpr(null),
                BinaryExpr.Operator.EQUALS
        );
        BinaryExpr isEmptyConditionCall = new BinaryExpr(
                new NameExpr(condition),
                new NullLiteralExpr(null),
                BinaryExpr.Operator.EQUALS
        );
        BinaryExpr combinedCondition = new BinaryExpr(isEmptyModelCall, isEmptyConditionCall, BinaryExpr.Operator.OR);
        IfStmt ifIsEmpty = new IfStmt(
                combinedCondition,
                new ReturnStmt(new IntegerLiteralExpr("0")),
                null
        );
        body.addStatement(ifIsEmpty);

        // 生成转换语句
        ClassOrInterfaceType entityType = new ClassOrInterfaceType(null, entityTableName);
        MethodCallExpr sourceToTargetCall = new MethodCallExpr(
                new NameExpr(BeanConvertUtils.class.getSimpleName()),
                "convertTo",
                new NodeList<>(
                        new NameExpr(model),
                        new NameExpr(entityTableName + "::new")
                )
        );
        VariableDeclarationExpr entitiesDeclaration = new VariableDeclarationExpr(
                new VariableDeclarator(
                        entityType,
                        entity,
                        sourceToTargetCall
                )
        );
        body.addStatement(entitiesDeclaration);

        // 生成 Integer result = baseDao.update(entity, getWrapper(condition));
        MethodCallExpr update = new MethodCallExpr(
                new NameExpr(baseDao),
                MethodNameConstant.UPDATE,
                NodeList.nodeList(
                        new NameExpr(entity), // 第一个参数：entity
                        new MethodCallExpr(
                                new NameExpr("this"), // getWrapper 方法调用
                                MethodNameConstant.REPOSITORY_GET_WRAPPER,
                                NodeList.nodeList(new NameExpr(condition)) // 参数：condition
                        )
                )
        );
        VariableDeclarationExpr resultSelectCount = new VariableDeclarationExpr(
                new VariableDeclarator(
                        type,
                        result,
                        update
                )
        );
        body.addStatement(resultSelectCount);

        // 生成返回语句: return result;
        body.addStatement(new ReturnStmt(new NameExpr(result)));

        methodDeclaration.setBody(body);
        return methodDeclaration;
    }

    /**
     * 生成 updateModel 方法
     * @param serviceUpdateModel
     * @param modelName
     * @param entityTableName
     * @return
     */
    private static MethodDeclaration updateModel(String serviceUpdateModel, String modelName, String entityTableName) {

        String model = "model";
        String result = "result";
        String entity = "entity";
        String baseDao = "baseDao";

        // 添加返回值类型
        ClassOrInterfaceType type = new ClassOrInterfaceType(null, Integer.class.getSimpleName());

        // 生成方法 updateModel
        MethodDeclaration methodDeclaration = new MethodDeclaration();
        methodDeclaration.setModifiers(Modifier.Keyword.PUBLIC);
        methodDeclaration.setType(type);
        methodDeclaration.setName(serviceUpdateModel);
        methodDeclaration.addAnnotation(Override.class);
        methodDeclaration.addParameter(new Parameter(new ClassOrInterfaceType(null, modelName), model));

        BlockStmt body = new BlockStmt();

        // 生成 if(model == null){ return 0; }
        BinaryExpr isEmptyCall = new BinaryExpr(
                new NameExpr(model),
                new NullLiteralExpr(null),
                BinaryExpr.Operator.EQUALS
        );
        IfStmt ifIsEmpty = new IfStmt(
                isEmptyCall,
                new ReturnStmt(new IntegerLiteralExpr("0")),
                null
        );
        body.addStatement(ifIsEmpty);

        // 生成转换语句
        ClassOrInterfaceType entityType = new ClassOrInterfaceType(null, entityTableName);
        MethodCallExpr sourceToTargetCall = new MethodCallExpr(
                new NameExpr(BeanConvertUtils.class.getSimpleName()),
                "convertTo",
                new NodeList<>(
                        new NameExpr(model),
                        new NameExpr(entityTableName + "::new")
                )
        );
        VariableDeclarationExpr entitiesDeclaration = new VariableDeclarationExpr(
                new VariableDeclarator(
                        entityType,
                        entity,
                        sourceToTargetCall
                )
        );
        body.addStatement(entitiesDeclaration);

        // 生成 Integer result = baseDao.updateById(entity);
        MethodCallExpr updateById = new MethodCallExpr(
                new NameExpr(baseDao),
                MethodNameConstant.UPDATE_BY_ID)
                .addArgument(entity);
        VariableDeclarationExpr resultSelectCount = new VariableDeclarationExpr(
                new VariableDeclarator(
                        type,
                        result,
                        updateById
                )
        );
        body.addStatement(resultSelectCount);


        // 生成返回语句: return result;
        body.addStatement(new ReturnStmt(new NameExpr(result)));
        methodDeclaration.setBody(body);
        return methodDeclaration;
    }

    /**
     * 生成 createBath 方法
     * @param serviceCreateBath
     * @param modelName
     * @param entityTableName
     * @return
     */
    private static MethodDeclaration createBath(String serviceCreateBath, String modelName, String entityTableName) {

        String models = "models";
        String result = "result";
        String number = "100";

        // 添加返回值类型
        ClassOrInterfaceType type = new ClassOrInterfaceType(null, Integer.class.getSimpleName());
        ClassOrInterfaceType modelType = new ClassOrInterfaceType(null, modelName);
        ClassOrInterfaceType ListType = new ClassOrInterfaceType(null, List.class.getSimpleName());
        ListType.setTypeArguments(modelType);

        // 生成方法 createBath
        MethodDeclaration methodDeclaration = new MethodDeclaration();
        methodDeclaration.setModifiers(Modifier.Keyword.PUBLIC);
        methodDeclaration.setType(type);
        methodDeclaration.setName(serviceCreateBath);
        methodDeclaration.addAnnotation(Override.class);
        methodDeclaration.addParameter(new Parameter(ListType, models));

        BlockStmt body = new BlockStmt();

        //生成 Integer result = this.createBatch(models, 100);
        MethodCallExpr insertBatchCall = new MethodCallExpr(
                new ThisExpr(),
                "createBath",
                new NodeList<>(
                        new NameExpr(models),
                        new NameExpr(number)
                )
        );
        VariableDeclarationExpr bDeclaration = new VariableDeclarationExpr(
                new VariableDeclarator(
                        new ClassOrInterfaceType().setName(Integer.class.getSimpleName()),
                        result,
                        insertBatchCall
                )
        );
        body.addStatement(bDeclaration);

        // 生成返回语句: return result;
        body.addStatement(new ReturnStmt(new NameExpr(result)));

        methodDeclaration.setBody(body);
        return methodDeclaration;
    }

    /**
     * 生成 createBathSize 方法
     * @param serviceCreateBath
     * @param modelName
     * @param entityTableName
     * @return
     */
    private static MethodDeclaration createBathSize(String serviceCreateBath, String modelName, String entityTableName) {

        String models = "models";
        String entities = "entities";
        String result = "result";
        String b = "b";
        String batchSize = "batchSize";
        String item = "item";
        String newId = "newId";
        int number = 100;

        // 添加返回值类型
        ClassOrInterfaceType type = new ClassOrInterfaceType(null, Integer.class.getSimpleName());
        ClassOrInterfaceType modelType = new ClassOrInterfaceType(null, modelName);
        ClassOrInterfaceType ListType = new ClassOrInterfaceType(null, List.class.getSimpleName());
        ListType.setTypeArguments(modelType);

        // 生成方法 createBathSize
        MethodDeclaration methodDeclaration = new MethodDeclaration();
        methodDeclaration.setModifiers(Modifier.Keyword.PUBLIC);
        methodDeclaration.setType(type);
        methodDeclaration.setName(serviceCreateBath);
        methodDeclaration.addAnnotation(Override.class);
        methodDeclaration.addParameter(new Parameter(ListType, models));
        methodDeclaration.addParameter(new Parameter(new ClassOrInterfaceType(null, Integer.class.getSimpleName()), batchSize));

        BlockStmt body = new BlockStmt();

        // 第一个 if 语句: if(CollectionUtils.isEmpty(models)){ return 0; }
        MethodCallExpr isEmptyCall = new MethodCallExpr(
                new NameExpr("CollectionUtils"),
                "isEmpty",
                new NodeList<>(new NameExpr(models))
        );
        IfStmt ifIsEmpty = new IfStmt(
                isEmptyCall,
                new ReturnStmt(new IntegerLiteralExpr("0")),
                null
        );
        body.addStatement(ifIsEmpty);

        // 第二个 if 语句: if(batchSize <= 0){ batchSize = 100; }
        BinaryExpr batchSizeCheck = new BinaryExpr(
                new NameExpr(batchSize),
                new IntegerLiteralExpr("0"),
                BinaryExpr.Operator.LESS_EQUALS
        );
        ExpressionStmt assignBatchSize = new ExpressionStmt(
                new AssignExpr(
                        new NameExpr(batchSize),
                        new IntegerLiteralExpr(number),
                        AssignExpr.Operator.ASSIGN
                )
        );
        IfStmt ifBatchSize = new IfStmt(
                batchSizeCheck,
                assignBatchSize,
                null
        );
        body.addStatement(ifBatchSize);

        // 初始化 result 变量: Integer result = 0;
        VariableDeclarationExpr resultDeclaration = new VariableDeclarationExpr(
                new VariableDeclarator(
                        new ClassOrInterfaceType().setName(Integer.class.getSimpleName()),
                        result,
                        new IntegerLiteralExpr("0")
                )
        );
        body.addStatement(resultDeclaration);

        // for 循环: for(T item : models)
        ForEachStmt forEachStmt = new ForEachStmt(
                new VariableDeclarationExpr(
                        new VariableDeclarator(
                                new ClassOrInterfaceType().setName(modelName),
                                item
                        )
                ),
                new NameExpr(models),
                new BlockStmt()
        );
        BlockStmt forEachBody = (BlockStmt) forEachStmt.getBody();

        // 在循环体内生成代码: long newId = IdWorker.getId(); item.setId(newId);
        MethodCallExpr getIdCall = new MethodCallExpr(
                new NameExpr("IdWorker"),
                "getId"
        );
        VariableDeclarationExpr newIdDeclaration = new VariableDeclarationExpr(
                new VariableDeclarator(
                        new ClassOrInterfaceType().setName(Long.class.getSimpleName()),
                        newId,
                        getIdCall
                )
        );
        forEachBody.addStatement(newIdDeclaration);

        MethodCallExpr setIdCall = new MethodCallExpr(
                new NameExpr(item),
                "setId",
                new NodeList<>(new NameExpr(newId))
        );
        forEachBody.addStatement(new ExpressionStmt(setIdCall));
        body.addStatement(forEachStmt);

        // 生成 entities 变量: List<T> entities = BeanConvertUtils.convertListTo(models, T::new);
        ClassOrInterfaceType entityType = new ClassOrInterfaceType()
                .setName(List.class.getSimpleName())
                .setTypeArguments(new ClassOrInterfaceType().setName(entityTableName));
        MethodCallExpr sourceToTargetCall = new MethodCallExpr(
                new NameExpr(BeanConvertUtils.class.getSimpleName()),
                "convertListTo",
                new NodeList<>(
                        new NameExpr(models),
                        new NameExpr(entityTableName + "::new")
                )
        );
        VariableDeclarationExpr entitiesDeclaration = new VariableDeclarationExpr(
                new VariableDeclarator(
                        entityType,
                        entities,
                        sourceToTargetCall
                )
        );
        body.addStatement(entitiesDeclaration);

        // 生成 insertBatch 调用: boolean b = this.insertBatch(entities, batchSize);
        MethodCallExpr insertBatchCall = new MethodCallExpr(
                new ThisExpr(),
                "insertBatch",
                new NodeList<>(
                        new NameExpr(entities),
                        new NameExpr(batchSize)
                )
        );
        VariableDeclarationExpr bDeclaration = new VariableDeclarationExpr(
                new VariableDeclarator(
                        new ClassOrInterfaceType().setName(Boolean.class.getSimpleName()),
                        b,
                        insertBatchCall
                )
        );
        body.addStatement(bDeclaration);

        // 生成 if 语句: if(b == true){ result = entities.size(); }
        BinaryExpr bCheck = new BinaryExpr(
                new NameExpr(b),
                new BooleanLiteralExpr(true),
                BinaryExpr.Operator.EQUALS
        );
        ExpressionStmt assignResult = new ExpressionStmt(
                new AssignExpr(
                        new NameExpr(result),
                        new MethodCallExpr(
                                new NameExpr(entities),
                                "size"
                        ),
                        AssignExpr.Operator.ASSIGN
                )
        );
        IfStmt ifB = new IfStmt(
                bCheck,
                assignResult,
                null
        );
        body.addStatement(ifB);

        // 生成返回语句: return result;
        body.addStatement(new ReturnStmt(new NameExpr(result)));

        methodDeclaration.setBody(body);
        return methodDeclaration;
    }

    /**
     * 生成create方法
     * @param serviceCreate
     * @param modelName
     * @param entityTableName
     * @return
     */
    private static MethodDeclaration create(String serviceCreate, String modelName, String entityTableName) {

        String model = "model";
        String entity = "entity";
        String result = "result";
        String baseDao = "baseDao";
        String setId = "setId";
        String getId = "getId";
        String id = "id";

        // 添加返回值类型
        ClassOrInterfaceType type = new ClassOrInterfaceType(null, Integer.class.getSimpleName());

        // 生成方法 create
        MethodDeclaration methodDeclaration = new MethodDeclaration();
        methodDeclaration.setModifiers(Modifier.Keyword.PUBLIC);
        methodDeclaration.setType(type);
        methodDeclaration.setName(serviceCreate);
        methodDeclaration.addAnnotation(Override.class);
        methodDeclaration.addParameter(new Parameter(new ClassOrInterfaceType(null, modelName), model));

        BlockStmt blockStmt = new BlockStmt();

        // 转换实体
        ClassOrInterfaceType entityTYpe = new ClassOrInterfaceType(null, entityTableName);
        MethodCallExpr modelMethodCallExpr = new MethodCallExpr(
                new NameExpr(BeanConvertUtils.class.getSimpleName()),
                "convertTo"
        );
        modelMethodCallExpr.addArgument(new NameExpr(model));
        modelMethodCallExpr.addArgument(new NameExpr(entityTableName + "::new"));
        VariableDeclarationExpr modelValuesVar = new VariableDeclarationExpr(
                new VariableDeclarator(
                        entityTYpe,
                        entity,
                        modelMethodCallExpr
                )
        );
        blockStmt.addStatement(modelValuesVar);

        //调用 insert 方法
        MethodCallExpr insert = new MethodCallExpr(
                new NameExpr(baseDao),
                MethodNameConstant.INSERT)
                .addArgument(entity);
        VariableDeclarationExpr resultSelectCount = new VariableDeclarationExpr(
                new VariableDeclarator(
                        type,
                        result,
                        insert
                )
        );
        blockStmt.addStatement(resultSelectCount);

        // 生成getId
        ClassOrInterfaceType longType = new ClassOrInterfaceType(null, Long.class.getSimpleName());
        MethodCallExpr methodCallExpr = new MethodCallExpr(
                new NameExpr(entity),
                getId
        );
        VariableDeclarationExpr resultValuesVar = new VariableDeclarationExpr(
                new VariableDeclarator(
                        longType,
                        id,
                        methodCallExpr
                )
        );
        blockStmt.addStatement(resultValuesVar);

        //设置setId
        MethodCallExpr setIdCall = new MethodCallExpr(
                new NameExpr(model),
                setId,
                new NodeList<>(new NameExpr(id))
        );
        blockStmt.addStatement(setIdCall);

        // 返回 pageData
        blockStmt.addStatement(new ReturnStmt(new NameExpr(result)));

        methodDeclaration.setBody(blockStmt);
        return methodDeclaration;
    }

    private static MethodDeclaration getPageList(String serviceGetPageList, String paramQueryBody,
                                                 String modelName, String translatorValue, String entityTableName) {

        String baseDao = "baseDao";
        String getPage = "getPage";
        String getPageData = "getPageData";
        String iPage = "iPage";
        String setTotal = "setTotal";
        String wrapper = "wrapper";
        String queryParams = "queryParams";
        String queryBody = "queryBody";
        String totalCount = "totalCount";
        String pageData = "pageData";

        // 添加返回值类型
        ClassOrInterfaceType type = new ClassOrInterfaceType(null, PageData.class.getSimpleName());
        ClassOrInterfaceType respList = new ClassOrInterfaceType(null, modelName);
        type.setTypeArguments(respList);

        // 生成方法 expandWrapper
        MethodDeclaration methodDeclaration = new MethodDeclaration();
        methodDeclaration.setModifiers(Modifier.Keyword.PUBLIC);
        methodDeclaration.setType(type);
        methodDeclaration.setName(serviceGetPageList);
        methodDeclaration.addAnnotation(Override.class);
        methodDeclaration.addParameter(new Parameter(new ClassOrInterfaceType(null, paramQueryBody), queryBody));

        // 生成方法
        BlockStmt blockStmt = new BlockStmt();
        ClassOrInterfaceType map = new ClassOrInterfaceType(null, Map.class.getSimpleName());
        MethodCallExpr toMap = new MethodCallExpr(
                new NameExpr(queryBody),
                MethodNameConstant.TO_MAP
        );
        VariableDeclarationExpr resultMap = new VariableDeclarationExpr(
                new VariableDeclarator(
                        map,
                        queryParams,
                        toMap
                )
        );
        blockStmt.addStatement(resultMap);

        ClassOrInterfaceType name = new ClassOrInterfaceType(null, entityTableName);
        ClassOrInterfaceType queryWrapperType = new ClassOrInterfaceType(null, QueryWrapper.class.getSimpleName());
        queryWrapperType.setTypeArguments(name);
        MethodCallExpr getWrapperCall = new MethodCallExpr(MethodNameConstant.REPOSITORY_GET_WRAPPER)
                .addArgument(queryBody);
        VariableDeclarationExpr resultValuesVar = new VariableDeclarationExpr(
                new VariableDeclarator(
                        queryWrapperType,
                        wrapper,
                        getWrapperCall
                )
        );
        blockStmt.addStatement(resultValuesVar);


        ClassOrInterfaceType iPageTYpe = new ClassOrInterfaceType(null, IPage.class.getSimpleName());
        iPageTYpe.setTypeArguments(name);
        VariableDeclarator iPageVar = new VariableDeclarator(iPageTYpe, iPage);
        blockStmt.addStatement(new VariableDeclarationExpr(iPageVar));
        // 创建 baseDao.selectPage 方法调用
        MethodCallExpr selectPage = new MethodCallExpr(
                new NameExpr(baseDao),
                MethodNameConstant.SELECT_PAGE,
                new NodeList<>(
                        new MethodCallExpr(new NameExpr("this"), getPage,
                                new NodeList<>(
                                        new NameExpr(queryParams),
                                        new NameExpr("null"),
                                        new BooleanLiteralExpr(false)
                                )
                        ),
                        new NameExpr(wrapper)
                )
        );
        // 生成赋值表达式
        ExpressionStmt assignmentStmt = new ExpressionStmt(
                new AssignExpr(
                        new NameExpr(iPage),
                        selectPage,
                        AssignExpr.Operator.ASSIGN
                )
        );
        blockStmt.addStatement(assignmentStmt);

        //生成selectCount
        ClassOrInterfaceType integerTYpe = new ClassOrInterfaceType(null, Integer.class.getSimpleName());
        MethodCallExpr selectCount = new MethodCallExpr(
                new NameExpr(baseDao),
                MethodNameConstant.SELECT_COUNT)
                .addArgument(wrapper);
        VariableDeclarationExpr resultSelectCount = new VariableDeclarationExpr(
                new VariableDeclarator(
                        integerTYpe,
                        totalCount,
                        selectCount
                )
        );
        blockStmt.addStatement(resultSelectCount);

        // 设置 iPage 的总数
        MethodCallExpr setTotalCall = new MethodCallExpr(
                new NameExpr(iPage),
                setTotal,
                new NodeList<>(new NameExpr(totalCount))
        );
        blockStmt.addStatement(setTotalCall);

        // 创建 PageData<T> 变量声明
        ClassOrInterfaceType pageDataType = new ClassOrInterfaceType()
                .setName("PageData")
                .setTypeArguments(new ClassOrInterfaceType().setName(modelName));

        VariableDeclarator pageDataVar = new VariableDeclarator(pageDataType, pageData);
        blockStmt.addStatement(new VariableDeclarationExpr(pageDataVar));
        // 调用 getPageData 方法
        MethodCallExpr getPageDataCall = new MethodCallExpr(
                new NameExpr("this"),
                getPageData,
                new NodeList<>(
                        new NameExpr(iPage),
                        new ClassExpr(new ClassOrInterfaceType().setName(modelName))
                )
        );
        blockStmt.addStatement(new ExpressionStmt(new AssignExpr(
                new NameExpr(pageData),
                getPageDataCall,
                AssignExpr.Operator.ASSIGN
        )));

        // 调用 fillInfoForGetPageList 方法
        MethodCallExpr fillInfoCall = new MethodCallExpr(
                new NameExpr(translatorValue),
                MethodNameConstant.FILL_INFO_FOR_GET_PAGE_LIST,
                new NodeList<>(new NameExpr(pageData))
        );
        blockStmt.addStatement(new ExpressionStmt(fillInfoCall));

        // 返回 pageData
        blockStmt.addStatement(new ReturnStmt(new NameExpr(pageData)));

        methodDeclaration.setBody(blockStmt);
        return methodDeclaration;
    }

    /**
     * 实现方法 getDetailById
     * @param serviceGetDetailByid
     * @param modelName
     * @param translatorValue
     * @param entityTableName
     * @return
     */
    private static MethodDeclaration getDetailById(String serviceGetDetailByid, String modelName, String translatorValue, String entityTableName) {

        String baseDao = "baseDao";
        String id = "id";
        String entity = "entity";
        String model = "model";
        String wrapper = "wrapper";
        String lambda = "lambda";
        String lambdaWrapper = "lambdaWrapper";
        String getId = "getId";

        // 添加返回值类型
        ClassOrInterfaceType type = new ClassOrInterfaceType(null, modelName);
        ClassOrInterfaceType name = new ClassOrInterfaceType(null, entityTableName);
        ClassOrInterfaceType queryWrapperType = new ClassOrInterfaceType(null, QueryWrapper.class.getSimpleName());
        queryWrapperType.setTypeArguments(name);
        // 生成方法
        MethodDeclaration methodDeclaration = new MethodDeclaration();
        methodDeclaration.setModifiers(Modifier.Keyword.PUBLIC);
        methodDeclaration.setType(type);
        methodDeclaration.setName(serviceGetDetailByid);
        methodDeclaration.addAnnotation(Override.class);
        methodDeclaration.addParameter(new Parameter(new ClassOrInterfaceType(null, Long.class.getSimpleName()), id));

        // 生成QueryWrapper<> wrapper = new QueryWrapper<>();
        ObjectCreationExpr initializationExpr = new ObjectCreationExpr(
                null, queryWrapperType, NodeList.nodeList());
        VariableDeclarator variableDeclarator = new VariableDeclarator(queryWrapperType,
                wrapper, initializationExpr);
        VariableDeclarationExpr variableDeclarationExpr = new VariableDeclarationExpr(variableDeclarator);
        BlockStmt blockStmt = new BlockStmt();
        blockStmt.addStatement(variableDeclarationExpr);

        // LambdaQueryWrapper<> lambdaWrapper = wrapper.lambda();
        ClassOrInterfaceType LambdaQueryWrapper = new ClassOrInterfaceType(null, LambdaQueryWrapper.class.getSimpleName());

        LambdaQueryWrapper.setTypeArguments(name);
        MethodCallExpr methodCall = new MethodCallExpr(
                new NameExpr(wrapper),
                lambda
        );
        VariableDeclarationExpr lambdaWrapperVar = new VariableDeclarationExpr(
                new VariableDeclarator(
                        LambdaQueryWrapper,
                        lambdaWrapper,
                        methodCall
                )
        );
        blockStmt.addStatement(lambdaWrapperVar);
        String eq =  lambdaWrapper + ".eq(%s, %s);";
        blockStmt.addStatement(String.format(eq, entityTableName + "::" + getId, "id"));
        MethodCallExpr methodCallExpr = new MethodCallExpr(
                new NameExpr(baseDao),
                MethodNameConstant.SELECT_ONE
        );
        methodCallExpr.addArgument(wrapper);
        VariableDeclarationExpr resultValuesVar = new VariableDeclarationExpr(
                new VariableDeclarator(
                        name,
                        entity,
                        methodCallExpr
                )
        );
        blockStmt.addStatement(resultValuesVar);

        MethodCallExpr modelMethodCallExpr = new MethodCallExpr(
                new NameExpr(BeanConvertUtils.class.getSimpleName()),
                "convertTo"
        );
        modelMethodCallExpr.addArgument(new NameExpr(entity));
        modelMethodCallExpr.addArgument(new NameExpr(modelName + "::new"));
        VariableDeclarationExpr modelValuesVar = new VariableDeclarationExpr(
                new VariableDeclarator(
                        type,
                        model,
                        modelMethodCallExpr
                )
        );
        blockStmt.addStatement(modelValuesVar);

        MethodCallExpr resultMethodCallExpr = new MethodCallExpr(
                new NameExpr(translatorValue),
                MethodNameConstant.FILL_INFO_FOR_GET_DETAIL_BY_ID
        );
        blockStmt.addStatement(resultMethodCallExpr);

        // 生成返回
        ReturnStmt returnStmt = new ReturnStmt(model);
        blockStmt.addStatement(returnStmt);
        methodDeclaration.setBody(blockStmt);
        return methodDeclaration;
    }

    /**
     * 实现方法 exists
     * @param serviceExists
     * @param paramQueryBody
     * @return
     */
    private static MethodDeclaration exists(String serviceExists, String paramQueryBody) {

        String queryBody = "queryBody";
        String count = "count";
        String is = " > 0";

        // 添加返回值类型
        ClassOrInterfaceType type = new ClassOrInterfaceType(null, Boolean.class.getSimpleName());
        ClassOrInterfaceType in = new ClassOrInterfaceType(null, Integer.class.getSimpleName());

        // 生成方法 expandWrapper
        MethodDeclaration methodDeclaration = new MethodDeclaration();
        methodDeclaration.setModifiers(Modifier.Keyword.PUBLIC);
        methodDeclaration.setType(type);
        methodDeclaration.setName(serviceExists);
        methodDeclaration.addAnnotation(Override.class);
        methodDeclaration.addParameter(new Parameter(new ClassOrInterfaceType(null, paramQueryBody), queryBody));

        MethodCallExpr methodCallExpr = new MethodCallExpr(
                new NameExpr("this"),
                MethodNameConstant.SERVICE_GET_COUNT
        );
        methodCallExpr.addArgument(queryBody);
        VariableDeclarationExpr resultValuesVar = new VariableDeclarationExpr(
                new VariableDeclarator(
                        in,
                        count,
                        methodCallExpr
                )
        );

        // 生成返回
        ReturnStmt returnStmt = new ReturnStmt(count+is);
        methodDeclaration.getBody().ifPresent(body -> body.addStatement(resultValuesVar));
        methodDeclaration.getBody().ifPresent(body -> body.addStatement(returnStmt));

        return methodDeclaration;

    }

    /**
     * 实现方法 getCount
     * @param serviceGetCount
     * @param paramQueryBody
     * @return
     */
    private static MethodDeclaration getCount(String serviceGetCount, String paramQueryBody) {

        String baseDao = "baseDao";
        String queryBody = "queryBody";
        String count = "count";

        // 添加返回值类型
        ClassOrInterfaceType type = new ClassOrInterfaceType(null, Integer.class.getSimpleName());

        // 生成方法 expandWrapper
        MethodDeclaration methodDeclaration = new MethodDeclaration();
        methodDeclaration.setModifiers(Modifier.Keyword.PUBLIC);
        methodDeclaration.setType(type);
        methodDeclaration.setName(serviceGetCount);
        methodDeclaration.addAnnotation(Override.class);
        methodDeclaration.addParameter(new Parameter(new ClassOrInterfaceType(null, paramQueryBody), queryBody));

        MethodCallExpr methodCallExpr = new MethodCallExpr(
                new NameExpr(baseDao),
                MethodNameConstant.SELECT_COUNT
        );
        MethodCallExpr getWrapperCall = new MethodCallExpr(MethodNameConstant.REPOSITORY_GET_WRAPPER)
                .addArgument(queryBody);
        methodCallExpr.addArgument(getWrapperCall);
        VariableDeclarationExpr resultValuesVar = new VariableDeclarationExpr(
                new VariableDeclarator(
                        type,
                        count,
                        methodCallExpr
                )
        );

        // 生成返回
        ReturnStmt returnStmt = new ReturnStmt(count);
        methodDeclaration.getBody().ifPresent(body -> body.addStatement(resultValuesVar));
        methodDeclaration.getBody().ifPresent(body -> body.addStatement(returnStmt));

        return methodDeclaration;
    }

    /**
     * /实现方法 getList
     * @param getList
     * @param paramQueryBody
     * @param modelName
     * @param translatorValue
     * @param entityTableName
     * @return
     */
    private static MethodDeclaration getList(String getList, String paramQueryBody, String modelName,
                                             String translatorValue, String entityTableName) {
        String baseDao = "baseDao";
        String list = "list";
        String modelList = "modelList";
        String queryBody = "queryBody";

        // 添加返回值类型
        ClassOrInterfaceType type = new ClassOrInterfaceType(null, List.class.getSimpleName());
        ClassOrInterfaceType respList = new ClassOrInterfaceType(null, modelName);
        type.setTypeArguments(respList);

        // 生成方法 expandWrapper
        MethodDeclaration methodDeclaration = new MethodDeclaration();
        methodDeclaration.setModifiers(Modifier.Keyword.PUBLIC);
        methodDeclaration.setType(type);
        methodDeclaration.setName(getList);
        methodDeclaration.addAnnotation(Override.class);
        methodDeclaration.addParameter(new Parameter(new ClassOrInterfaceType(null, paramQueryBody), queryBody));

        // 调用方法
        ClassOrInterfaceType resultModelType = new ClassOrInterfaceType(null, entityTableName);
        ClassOrInterfaceType resultListType = new ClassOrInterfaceType(null, List.class.getSimpleName());
        resultListType.setTypeArguments(resultModelType);
        MethodCallExpr methodCallExpr = new MethodCallExpr(
                new NameExpr(baseDao),
                MethodNameConstant.SELECT_LIST
        );
        MethodCallExpr getWrapperCall = new MethodCallExpr(MethodNameConstant.REPOSITORY_GET_WRAPPER)
                .addArgument(queryBody);
        methodCallExpr.addArgument(getWrapperCall);
        VariableDeclarationExpr resultValuesVar = new VariableDeclarationExpr(
                new VariableDeclarator(
                        resultListType,
                        list,
                        methodCallExpr
                )
        );

        MethodCallExpr modelMethodCallExpr = new MethodCallExpr(
                new NameExpr(BeanConvertUtils.class.getSimpleName()),
                "convertListTo"
        );
        modelMethodCallExpr.addArgument(new NameExpr(list));
        modelMethodCallExpr.addArgument(new NameExpr(modelName + "::new"));
        VariableDeclarationExpr modelValuesVar = new VariableDeclarationExpr(
                new VariableDeclarator(
                        type,
                        modelList,
                        modelMethodCallExpr
                )
        );

        MethodCallExpr resultMethodCallExpr = new MethodCallExpr(
                new NameExpr(translatorValue),
                MethodNameConstant.FILL_INFO_FOR_GET_LIST
        );

        // 生成返回
        ReturnStmt returnStmt = new ReturnStmt(modelList);
        methodDeclaration.getBody().ifPresent(body -> body.addStatement(resultValuesVar));
        methodDeclaration.getBody().ifPresent(body -> body.addStatement(modelValuesVar));
        methodDeclaration.getBody().ifPresent(body -> body.addStatement(resultMethodCallExpr));
        methodDeclaration.getBody().ifPresent(body -> body.addStatement(returnStmt));

        return methodDeclaration;
    }

    /**
     *
     * @param repositoryExpandWrapper 方法名
     * @param paramQueryBody 传参类
     * @param entityTableName 实体类
     * @return
     */
    private static MethodDeclaration expandWrapper(String repositoryExpandWrapper, String paramQueryBody, String entityTableName) {
        String explanatory ="/**\n" +
                "\t * 拓展查询条件\n" +
                "\t * \n" +
                "\t * @param params %s \n" +
                "\t * @param wrapper QueryWrapper<%s> \n" +
                "\t * @return QueryWrapper<%s>\n" +
                "\t */";
        String params = "params";
        String wrapper = "wrapper";
        String lambda = "lambda";
        String lambdaWrapper = "lambdaWrapper";

        // 添加返回值类型
        ClassOrInterfaceType type = new ClassOrInterfaceType(null, QueryWrapper.class.getSimpleName());
        ClassOrInterfaceType respList = new ClassOrInterfaceType(null, entityTableName);
        type.setTypeArguments(respList);

        // 生成方法 expandWrapper
        MethodDeclaration methodDeclaration = new MethodDeclaration();
        methodDeclaration.setModifiers(Modifier.Keyword.PUBLIC);
        methodDeclaration.setType(type);
        methodDeclaration.setName(repositoryExpandWrapper);
        methodDeclaration.addParameter(new Parameter(new ClassOrInterfaceType(null, paramQueryBody), params));
        methodDeclaration.addParameter(new Parameter(type, wrapper));
        methodDeclaration.setJavadocComment(String.format(explanatory, paramQueryBody, entityTableName, paramQueryBody, entityTableName));

        BlockStmt blockStmt = new BlockStmt();

        // LambdaQueryWrapper<> lambdaWrapper = wrapper.lambda();
        ClassOrInterfaceType LambdaQueryWrapper = new ClassOrInterfaceType(null, LambdaQueryWrapper.class.getSimpleName());
        ClassOrInterfaceType name = new ClassOrInterfaceType(null, entityTableName);
        LambdaQueryWrapper.setTypeArguments(name);
        MethodCallExpr methodCallExpr = new MethodCallExpr(
                new NameExpr(wrapper),
                lambda
        );
        VariableDeclarationExpr resultValuesVar = new VariableDeclarationExpr(
                new VariableDeclarator(
                        LambdaQueryWrapper,
                        lambdaWrapper,
                        methodCallExpr
                )
        );
        blockStmt.addStatement(resultValuesVar);

        ReturnStmt returnStmt = new ReturnStmt(wrapper);
        blockStmt.addStatement(returnStmt);
        methodDeclaration.setBody(blockStmt);
        return methodDeclaration;
    }

    /**
     *
     * @param repositoryGetWrapper 方法名
     * @param paramQueryBody 传参类
     * @param entityTableName 实体类
     * @param paramsAttribute  paramQueryBody 类里的属性类型
     * @param entityAttribute  entity 类里的属性类型
     * @return
     */
    private static MethodDeclaration getWrapper(String repositoryGetWrapper, String paramQueryBody, String entityTableName,
                                                Map<String, Object> paramsAttribute, Map<String, List<String>> entityAttribute){
        String explanatory = "@generate 生成的方法不可修改\n" +
                "\t 如需拓展查询条件，在 expandWrapper 中添加：\n" +
                "\t @see {@link #expandWrapper(%s, QueryWrapper<%s>)}\n" +
                "\t \n" +
                "\t @param params 条件\n" +
                "\t @return \n" +
                "\t \n" +
                "\t @param params %s \n" +
                "\t @return QueryWrapper<%s>";
        String params = "params";
        String wrapper = "wrapper";
        String lambda = "lambda";
        String lambdaWrapper = "lambdaWrapper";

        // 添加返回值类型
        ClassOrInterfaceType type = new ClassOrInterfaceType(null, QueryWrapper.class.getSimpleName());
        ClassOrInterfaceType respList = new ClassOrInterfaceType(null, entityTableName);
        type.setTypeArguments(respList);

        // 生成方法 getWrapper
        MethodDeclaration methodDeclaration = new MethodDeclaration();
        methodDeclaration.setModifiers(Modifier.Keyword.PUBLIC);
        methodDeclaration.setType(type);
        methodDeclaration.setName(repositoryGetWrapper);
        methodDeclaration.addParameter(new Parameter(new ClassOrInterfaceType(null, paramQueryBody), params));
        methodDeclaration.setJavadocComment(String.format(explanatory, paramQueryBody, entityTableName, paramQueryBody, entityTableName));

        // 生成QueryWrapper<> wrapper = new QueryWrapper<>();
        ObjectCreationExpr initializationExpr = new ObjectCreationExpr(
                null, type, NodeList.nodeList());
        VariableDeclarator variableDeclarator = new VariableDeclarator(type,
                wrapper, initializationExpr);
        VariableDeclarationExpr variableDeclarationExpr = new VariableDeclarationExpr(variableDeclarator);
        BlockStmt blockStmt = new BlockStmt();
        blockStmt.addStatement(variableDeclarationExpr);

        IfStmt ifStmtNULL = new IfStmt();
        ifStmtNULL.setCondition(new BinaryExpr(new NameExpr(params), new NullLiteralExpr(), BinaryExpr.Operator.EQUALS));
        // 生成返回
        ReturnStmt returnStmt = new ReturnStmt(wrapper);
        ifStmtNULL.setThenStmt(returnStmt);
        blockStmt.addStatement(ifStmtNULL);

        // LambdaQueryWrapper<> lambdaWrapper = wrapper.lambda();
        ClassOrInterfaceType LambdaQueryWrapper = new ClassOrInterfaceType(null, LambdaQueryWrapper.class.getSimpleName());
        ClassOrInterfaceType name = new ClassOrInterfaceType(null, entityTableName);
        LambdaQueryWrapper.setTypeArguments(name);
        MethodCallExpr methodCallExpr = new MethodCallExpr(
                new NameExpr(wrapper),
                lambda
        );
        VariableDeclarationExpr resultValuesVar = new VariableDeclarationExpr(
                new VariableDeclarator(
                        LambdaQueryWrapper,
                        lambdaWrapper,
                        methodCallExpr
                )
        );
        blockStmt.addStatement(resultValuesVar);

        // 增加判断条件
        //lambdaWrapper.eq(params.getId() != null, DoctorBillEntity::getId, params.getId());
        //lambdaWrapper.in(CollectionUtils.isNotEmpty(params.getIdList()), DoctorBillEntity::getId, params.getIdList());
        //lambdaWrapper.eq(StringUtils.isNotBlank(params.getBillOrderNumber()), DoctorBillEntity::getBillOrderNumber, params.getBillOrderNumber());
        String eq =  lambdaWrapper + ".eq(%s != null, %s, %s);";
        String strEq = lambdaWrapper + ".eq(StringUtils.isNotBlank(%s), %s, %s);";
        //String strLike = lambdaWrapper + ".like(StringUtils.isNotBlank(%s), %s, %s);";
        String in = lambdaWrapper + ".in(CollectionUtils.isNotEmpty(%s), %s, %s);";
        // 大于
        String dateGt = lambdaWrapper + ".gt(%s != null, %s, %s);";
        // 小于
        String dateLt = lambdaWrapper + ".lt(%s != null, %s, %s);";
        // 大于等于
        String dateGe = lambdaWrapper + ".ge(%s != null, %s, %s);";
        // 小于等于
        String dateLe = lambdaWrapper + ".le(%s != null, %s, %s);";

        List<String> validTypes = Arrays.asList(Long.class.getSimpleName(), Integer.class.getSimpleName(),
                String.class.getSimpleName(), BigDecimal.class.getSimpleName(), Double.class.getSimpleName(),
                Float.class.getSimpleName(), Boolean.class.getSimpleName(), Date.class.getSimpleName());
        for (Map.Entry<String, Object> entry  : paramsAttribute.entrySet()) {
            // 基本数据类型eq =比较
            Object valueType = entry.getValue();
            String key = entry.getKey();
            String elementType = "";

            // 是否有相关的集合
            // 是否有对应基本数据类型
            if (!validTypes.contains(valueType.toString()) || !entityAttribute.containsKey(valueType.toString())) {
                if (!valueType.toString().contains(List.class.getSimpleName())) {
                    continue;
                }
                // 通过正则表达式匹配出泛型名称// 匹配类似 "<Long>" 的泛型部分
                String listType = (String) valueType;
                elementType = listType.substring(listType.indexOf("<") + 1, listType.indexOf(">"));
                log.info("List<>中泛型元素类型为 = {}",elementType );
            }

            List<String> entityType = entityAttribute.containsKey(valueType.toString()) ? entityAttribute.get(valueType.toString()) :
                    entityAttribute.containsKey(elementType) ? entityAttribute.get(elementType) : new ArrayList<>();
            // 是否有对应变量名
            for (String attribute : entityType) {
                if (key.contains(attribute)) {
                    String paramsName = AttributeConvertUtils.tableNameToJava(key, TableNameConstant.TABLE_PREFIX, true) + "()";
                    String entityName = AttributeConvertUtils.tableNameToJava(attribute, TableNameConstant.TABLE_PREFIX, true);
                    if (valueType.toString().equals(String.class.getSimpleName())) {
                        blockStmt.addStatement(formatStringNotBlank(strEq, paramsName, params, entityTableName, entityName));

                        // 集合类型
                    } else if (valueType.toString().contains(List.class.getSimpleName())){
                        blockStmt.addStatement(formatString(in, paramsName, params, entityTableName, entityName));

                        // 时间类型生成相关
                    } else if (valueType.toString().contains(Date.class.getSimpleName())) {
                        processSwitchCase(blockStmt , paramsName, params, entityTableName, entityName, key, attribute,  eq, dateGt, dateLt, dateGe, dateLe);

                    } else {
                        blockStmt.addStatement(formatString(eq, paramsName, params, entityTableName, entityName));
                    }
                    break;
                }
            }
        }

        //expandWrapper(params, wrapper);
        //return wrapper;
        MethodCallExpr resultMethodCallExpr = new MethodCallExpr(
                MethodNameConstant.REPOSITORY_EXPAND_WRAPPER
        ).addArgument(params).addArgument(wrapper);
        blockStmt.addStatement(resultMethodCallExpr);
        blockStmt.addStatement(returnStmt);
        methodDeclaration.setBody(blockStmt);
        return methodDeclaration;
    }

    private static String formatStringNotBlank(String format, String paramsName, String params, String entityTableName, String entityName) {
        return String.format(format, params + ".get" + paramsName,
                entityTableName + "::get" + entityName,
                params + ".get" + paramsName);
    }

    private static void processSwitchCase(BlockStmt blockStmt, String paramsName, String params, String entityTableName,
                                          String entityName, String key, String attribute, String eq, String dateGt, String dateLt,
                                          String dateGe, String dateLe) {
        String keyGt = attribute + "Gt";
        String keyLt = attribute + "Lt";
        String keyGe = attribute + "Gte";
        String keyLe = attribute + "Lte";
        if (key.equals(attribute)) {
            blockStmt.addStatement(formatString(eq, paramsName, params, entityTableName, entityName));
        } else if (keyGt.equals(key)) {
            blockStmt.addStatement(formatString(dateGt, paramsName, params, entityTableName, entityName));
        } else if (keyLt.equals(key)) {
            blockStmt.addStatement(formatString(dateLt, paramsName, params, entityTableName, entityName));
        }  else if (keyGe.equals(key)) {
            blockStmt.addStatement(formatString(dateGe, paramsName, params, entityTableName, entityName));
        }  else if (keyLe.equals(key)) {
            blockStmt.addStatement(formatString(dateLe, paramsName, params, entityTableName, entityName));
        }
    }

    private static String formatString(String format, String paramsName, String params, String entityTableName, String entityName) {
        return String.format(format, params + ".get" + paramsName, entityTableName + "::get" + entityName, params + ".get" + paramsName);
    }

    /**
     *
     * @param repositoryGetWrapper 方法名称
     * @param paramQueryBody 传参类
     * @param entityName 实体类
     * @return
     */
    private static MethodDeclaration getWrapperImpl(String repositoryGetWrapper, String paramQueryBody, String entityName) {

        String explanatory = "废弃不使用\n" +
                "\t 推荐使用：\n" +
                "\t @see {@link #getWrapper(%s)}\n" +
                "\t \n" +
                "\t @param params 条件\n" +
                "\t @return \n" +
                "\t \n" +
                "\t @param params Map<String, Object> \n" +
                "\t @return QueryWrapper<%s>";
        String params = "params";

        // 添加返回值类型
        ClassOrInterfaceType type = new ClassOrInterfaceType(null, QueryWrapper.class.getSimpleName());
        ClassOrInterfaceType respList = new ClassOrInterfaceType(null, entityName);
        type.setTypeArguments(respList);

        // 生成方法 getWrapper
        MethodDeclaration methodDeclaration = new MethodDeclaration();
        methodDeclaration.setModifiers(Modifier.Keyword.PUBLIC);
        methodDeclaration.setType(type);
        methodDeclaration.setName(repositoryGetWrapper);
        methodDeclaration.addParameter(new Parameter(new ClassOrInterfaceType(null, "Map<String, Object>"), params));
        methodDeclaration.setJavadocComment(String.format(explanatory, paramQueryBody, entityName));
        // 生成注解
        methodDeclaration.addAnnotation(Override.class);

        // 生成返回
        ReturnStmt returnStmt = new ReturnStmt(new NameExpr("null"));
        methodDeclaration.getBody().ifPresent(body -> body.addStatement(returnStmt));
        return methodDeclaration;
    }
}
